package com.gopay.bis.manager.bank.Wap;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.TransUtils;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.icbc.ebank.pay.IcbcB2cMessage;
import com.gopay.common.domain.bank.icbc.ebank.pay.req.PayCustomB2CReq;
import com.gopay.common.domain.bank.icbc.ebank.pay.req.PayMessageWapB2CReq;
import com.gopay.common.domain.bank.icbc.ebank.pay.req.PayOrderInfoWapB2CReq;
import com.gopay.common.domain.bank.icbc.ebank.pay.req.PayWapB2CReq;
import com.gopay.common.domain.bank.icbc.ebank.query.req.CmsQueryB2CReq;
import com.gopay.common.domain.bank.icbc.ebank.query.req.EbQueryB2CReq;
import com.gopay.common.domain.bank.icbc.ebank.query.req.InQueryB2CReq;
import com.gopay.common.domain.bank.icbc.ebank.query.req.PubQueryB2CReq;
import com.gopay.common.domain.bank.icbc.ebank.query.res.CmsQueryB2CRes;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.DateUtils;
import com.gopay.remote.bank.WapPayManagerRemoteService;
import com.gopay.remote.bank.businesses.BankService;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

/**
 * 工行Wap支付B2C对象封装
 * @author wangjiqing
 *
 */
public class IcbcWapB2cManager implements WapPayManagerRemoteService{
	private static Logger logger = LoggerFactory.getLogger(IcbcWapB2cManager.class);
	
    private static final String XMLHEADER_B2C = "<?xml version=\"1.0\" encoding=\"GBK\" standalone=\"no\" ?>\n";
    
    private static final String XMLHEADER_QUERY = "<?xml version=\"1.0\" encoding=\"GB2312\" ?>\n";
    
    @Resource(name = "icbcWapBankServiceClient")
    private BankService icbcWapBankServiceClient;
    
    @Resource(name = "icbcConfig")
    private Map<String, String> icbcConfig;
    
    /**
     * 工行B2C签名
     * 
     * @param BaseMessage
     * @return Object
     * @throws GopayException
     */
    @Override
	public Object sign(BaseMessage message) throws GopayException {
    	IcbcB2cMessage messageB2C = (IcbcB2cMessage) message;
    	messageB2C.setGoodsId(" ");
    	messageB2C.setGoodsName(" ");
    	messageB2C.setGoodsNum(" ");
    	messageB2C.setCarriageAmt(" ");
    	messageB2C.setMerHint(" ");
    	messageB2C.setRemark1(" ");
    	messageB2C.setRemark2(" ");
    	messageB2C.setMerVAR(" ");
    	messageB2C.setBackup1(" ");
    	messageB2C.setBackup2(" ");
    	messageB2C.setBackup3(" ");
    	messageB2C.setBackup4(" ");
    	message.setOrderDate(updateTime());
    	messageB2C.setBankUrl(messageB2C.getPayUrl());
    	messageB2C.setMerUrl(messageB2C.getPayRuturnUrl());
    	messageB2C.setInterfaceName(icbcConfig.get("ICBC.WAP.B2C.INTERFACENAME"));
    	messageB2C.setInterfaceVersion(icbcConfig.get("ICBC.WAP.B2C.INTERFACEVERSION"));
    	messageB2C.setInstallmentTimes(icbcConfig.get("ICBC.B2C.INSTALLMENTTIMES"));
    	messageB2C.setMeracct(icbcConfig.get("ICBC.WAP.B2C.MERACCT"));
    	messageB2C.setVerifyJoinFlag(icbcConfig.get("ICBC.WAP.B2C.VERIFYJOINFLAG"));
    	messageB2C.setLanguage("zh_CN");
    	messageB2C.setCurType(icbcConfig.get("ICBC.CURCODE.RMB"));
    	messageB2C.setMerid(messageB2C.getMerID());
        messageB2C.setNotifyType(icbcConfig.get("ICBC.B2C.NOTIFYTYPE"));
        messageB2C.setResultType(icbcConfig.get("ICBC.B2C.RESULTTYPE"));
        messageB2C.setPlainMessage(buildPlain(messageB2C));
        BankLogUtils.printB2CManagerSignSendLog(messageB2C);     
		messageB2C = (IcbcB2cMessage) icbcWapBankServiceClient.sign(messageB2C);
        BankLogUtils.printB2CManagerSignReturnLog(messageB2C);
        return messageB2C;
		
	}

    /**
     * 工行B2C验签
     */
	@Override
	public Object verify(BaseMessage message) throws GopayException {
		BankLogUtils.printB2CManagerVerifySendLog(message);
    	Map<String, Object> map;    	
        map = (Map<String, Object>) icbcWapBankServiceClient.verify(message);
        BankLogUtils.printB2CManagerVerifyReturnLog(message, map);
        return map;
	}
	public String buildPlain(IcbcB2cMessage message){
		PayWapB2CReq payB2C = new PayWapB2CReq();
        PayOrderInfoWapB2CReq orderInfo = new PayOrderInfoWapB2CReq();   
        PayCustomB2CReq payCustom = new PayCustomB2CReq();
        PayMessageWapB2CReq payMessage =new PayMessageWapB2CReq();
        
        payB2C.setInterfaceName(message.getInterfaceName());
        payB2C.setInterfaceVersion(message.getInterfaceVersion());
        
        orderInfo.setOrderDate(message.getOrderDate());
        orderInfo.setOrderid(message.getOrderId());
        orderInfo.setSubAmount(message.getAmount().movePointRight(2).toString());   
        orderInfo.setInstallmentTimes(message.getInstallmentTimes());
        orderInfo.setCurType(message.getCurType());
        orderInfo.setMerId(message.getMerid());
        orderInfo.setMerAcct(message.getMeracct());
        
        payCustom.setVerifyJoinFlag(message.getVerifyJoinFlag());
        payCustom.setLanguage(message.getLanguage());

        payMessage.setGoodsID(message.getGoodsId());
        payMessage.setGoodsName(message.getGoodsName());
        payMessage.setGoodsNum(message.getGoodsNum());
        payMessage.setCarriageAmt(message.getCarriageAmt());
        payMessage.setMerHint(message.getMerHint());
        payMessage.setRemark1(message.getRemark1());
        payMessage.setRemark2(message.getRemark2());
        payMessage.setMerURL(message.getMerUrl());
        payMessage.setMerVAR(message.getMerVAR());
        payMessage.setNotifyType(message.getNotifyType());
        payMessage.setResultType(message.getResultType());
        payMessage.setBackup1(message.getBackup1());
        payMessage.setBackup2(message.getBackup2());
        payMessage.setBackup3(message.getBackup3());
        payMessage.setBackup4(message.getBackup4());
        
        payB2C.setOrderInfo(orderInfo);
        payB2C.setCustom(payCustom);
        payB2C.setMessage(payMessage);

        XStream xs = new XStream(new DomDriver());
        xs.autodetectAnnotations(true);
        String xml = xs.toXML(payB2C);
        xml = xml.replaceAll("\r", "");
        xml = xml.replaceAll("\n", "");
        xml = xml.replaceAll(" ", "");
        xml = xml.trim();    
        StringBuffer sb = new StringBuffer(XMLHEADER_B2C);
        sb.append(xml);
        return sb.toString();
		
	}

	public String updateTime(){
	    String time =DateUtils.getCurrDate();
	    System.out.println("系统时间----"+time);
	  //  return time.substring(0,5)+"921"+time.substring(8, 14);
	    return time;
	  //return  DateUtils.format(DateUtils.add(DateUtils.strToDate(time.substring(0,5)+"921"+time.substring(8, 14)), Calendar.MINUTE, -10));
	}
	public static void main(String[] args) {
        String time=DateUtils.getCurrDate();
        System.out.println(DateUtils.format(DateUtils.add(DateUtils.strToDate(time.substring(0,5)+"922"+time.substring(8, 14)), Calendar.MINUTE, -10)));
    }
	@Override
	public Object dayend(BaseMessage arg0) throws GopayException, Exception {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * 工行B2C查询
	 */
	@Override
	public Object query(Object message) throws GopayException {
		IcbcB2cMessage messageB2C = (IcbcB2cMessage) message;
        CmsQueryB2CReq cms = buildCms(messageB2C);
        Map<String, String> param = queryParam(cms);
        BankLogUtils.printB2CManagerQuerySendLog(messageB2C, param);
        CmsQueryB2CRes res;
        res = (CmsQueryB2CRes) icbcWapBankServiceClient.query(param);
        res.setOutStlmCd(BankConstants.BANK_LOGO_ICBC); // 为了区分日志输出
        BankLogUtils.printB2CManagerQueryReturnLog(res);
        return res;
	}

	/**
	 * 构建B2C查询对象
	 * @param message
	 * @return
	 */
	private CmsQueryB2CReq buildCms(IcbcB2cMessage message) {
        CmsQueryB2CReq cms = new CmsQueryB2CReq();
        EbQueryB2CReq eb = new EbQueryB2CReq();
        PubQueryB2CReq pub = new PubQueryB2CReq();
        InQueryB2CReq in = new InQueryB2CReq();
        // 交易代码
        pub.setTransCode(icbcConfig.get("ICBC.B2C.QUERY.TRANDCODE"));
        // 集团CIS
        pub.setCis(icbcConfig.get("ICBC.QUERY.CIS"));
        // 归属银行编号
        pub.setBankCode(icbcConfig.get("ICBC.QUERY.BANKCODE"));
        // 证书ID
        pub.setId(message.getMerID2nd());
        // 交易日期
        pub.setTranDate(DateUtils.getCurrDate("yyyyMMdd"));
        // 交易时间(微秒补零)
        pub.setTranTime(DateUtils.getCurrDate("HHmmssSS") + "000");
        // 指令包序列号
        pub.setFseqNo(TransUtils.getPackageID());
        // 商城类型
        in.setShopType(icbcConfig.get("ICBC.B2C.QUERY.SHOPTYPE"));
        // 商城代码
        in.setShopCode(icbcConfig.get("ICBC.B2C.QUERY.SHOPCODE"));
        // 商城账号
        in.setShopAcct(icbcConfig.get("ICBC.B2C.QUERY.SHOPACCT"));
        // 待查订单号
        in.setQryOrderNum(message.getOrderId());
        // 待查交易序列号
        in.setQrySerialNo(" ");
        // 起始日期
        in.setBeginDate(DateUtils.getCurrDate("yyyyMMdd"));
        // 截止日期
        in.setEndDate(DateUtils.getCurrDate("yyyyMMdd"));
        // 开始时间
        in.setBeginTime("000000");
        // 终止时间
        in.setEndTime("235959");
        // 查询交易状态类型
        in.setResultType(" ");
        // 查询下页标识
        in.setNextTag(" ");
        // 请求备用字段1
        in.setReqRes1(" ");
        // 请求备用字段2
        in.setReqRes2(" ");
        eb.setPub(pub);
        eb.setIn(in);
        cms.setEb(eb);  
        cms.setQueryUrl(message.getQueryUrl());
       
        return cms;
    }
	
	/**
	 * 构建B2C查询参数
	 * @param req
	 * @return
	 */
	private Map<String, String> queryParam(CmsQueryB2CReq req) {
        XStream xs = new XStream(new DomDriver());
        xs.autodetectAnnotations(true);
        // 生成请求报文
        String reqData = xs.toXML(req);
        StringBuffer sb = new StringBuffer(XMLHEADER_QUERY);
        sb.append(reqData);
        EbQueryB2CReq eb = req.getEb();
        PubQueryB2CReq pub = eb.getPub();
        Map<String, String> param = new HashMap<String, String>();
        param.put("userID", pub.getId());
        param.put("PackageID", pub.getFseqNo());
        param.put("SendTime", DateUtils.getCurrDate("yyyyMMddHHmmssSSS"));
        param.put("Version", icbcConfig.get("ICBC.QUERY.VERSION"));
        param.put("TransCode", pub.getTransCode());
        param.put("BankCode", pub.getBankCode());
        param.put("GroupCIS", pub.getCis());
        param.put("ID", pub.getId());
        param.put("PackageID", pub.getFseqNo());
        param.put("Cert", "");
        param.put("reqData", sb.toString());
        // 设置B2B交易
        param.put("tradeType", BankConstants.TRADE_B2C + "");
        param.put("queryUrl", req.getQueryUrl());
        return param;
    }

	

}
